#include "log.h"
// Logger类
std::string LogLevel::LevelToString(LogLevel::level level) {
  switch (level) {
    case 0:
      return "FATAL";
    case 100:
      return "ALERT";
    case 200:
      return "CRIT";
    case 300:
      return "ERROR";
    case 400:
      return "WARN";
    case 500:
      return "NOTICE";
    case 600:
      return "INFO";
    case 700:
      return "DEBUG";
    default:
      return "NOTSET";
  }
}
Logger::Logger(std::string& name) : name_(name) {}
void Logger::Log(LogEvent::ptr event) {
  for (auto& appender : appenders_) appender->Log(event);
}
void Logger::AddAppender(LogAppender::ptr appender) {
  appenders_.push_back(appender);
}
void Logger::DelAppender(LogAppender::ptr appender) {
  auto it = appenders_.find(appender);
}

// Formatter定义

// "%d{%Y-%m-%d %H:%M:%S} [%rms]%T%t%T%N%T%F%T[%p]%T[%c]%T%f:%l%T%m%n"
// 有限状态机，就两个状态：正在解析模板字符和正在解析常规字符
void LogFormatter::Init() {
  bool status = true;  // true表示正在解析常规字符,false表示正在解析模板字符。
  std::string tmp;  // 存储常规字符串
  std::unordered_map<int, std::string> patterns;
  std::string date_fmt;
  for (int i = 0; i < pattern_.size(); ++i) {
    std::string c = std::string(1, pattern_[i]);
    if (c == "%") {
      if (status) {
        if (tmp.size()) {
          patterns.insert({0, tmp});
          tmp.clear();
        }
        status = false;
        continue;
      } else {  // %%
        patterns.insert({1, c});
        status = true;
        continue;
      }
    } else {  // not %
      if (status) {
        tmp += c;
        continue;
      } else {
        patterns.insert({1, c});
        status = true;
        // 后面是对%d的特殊处理，如果%d后面直接跟了一对大括号，那么把大括号里面的内容提取出来作为date_fmt
        if (c != "d") continue;
        ++i;
        if (i < pattern_.size() && pattern_[i] != '{') continue;
        i++;
        while (i < pattern_.size() && pattern_[i] != '}') {
          date_fmt.push_back(pattern_[i++]);
        }
        if (pattern_[i] != '}') {
          std::cout << "[ERROR] LogFormatter::init() "
                    << "pattern: [" << pattern_ << "] '{' not closed"
                    << std::endl;
          break;
        }
      }
    }
  }

  static std::unordered_map<
      std::string, std::function<FormatItem::ptr(const std::string& str)>>
      s_format_items = {
#define XX(str, C)                                                           \
  {                                                                          \
#str, [](const std::string& fmt) { return FormatItem::ptr(new C(fmt)); } \
  }

          XX(m, MessageFormatItem),  // m:消息
  //   XX(p, LevelFormatItem),       // p:日志级别
  //   XX(c, LoggerNameFormatItem),  // c:日志器名称
  //   //        XX(d, DateTimeFormatItem),          // d:日期时间
  //   XX(r, ElapseFormatItem),       // r:累计毫秒数
  //   XX(f, FileNameFormatItem),     // f:文件名
  //   XX(l, LineFormatItem),         // l:行号
  //   XX(t, ThreadIdFormatItem),     // t:编程号
  //   XX(F, FiberIdFormatItem),      // F:协程号
  //   XX(N, ThreadNameFormatItem),   // N:线程名称
  //   XX(%, PercentSignFormatItem),  // %:百分号
  //   XX(T, TabFormatItem),          // T:制表符
  //   XX(n, NewLineFormatItem),      // n:换行符
#undef XX
      };

  for (auto& v : patterns) {
    if (v.first == 0) {
      // 常规字符
    } else if (v.second == "d") {
      // 日期
    } else {
      // 模式字符
      // 找不到的情况
    }
  }
}
void LogFormatter::Format(std::ostream& os, LogEvent::ptr event) {
  for (auto& item : items_) item->Format(os, event);
}
void LineFormatItem::Format(std::ostream& os, LogEvent::ptr event) {
  os << event->GetLine();
}
void FileFormatItem::Format(std::ostream& os, LogEvent::ptr event) {
  os << event->GetFile();
}

// LogEventWrapper类
LogEventWrapper::~LogEventWrapper() { logger_->Log(event_); }

// StdoutLogAppender类
void StdoutLogAppender::Log(LogEvent::ptr event) {
  formatter_->Format(std::cout, event);
}

int main() {
  std::cout << LogLevel::LevelToString(LogLevel::ALERT) << std::endl;
  return 0;
}